package com.ruoyi.common.log;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.UUID;

/**
 * @author cc
 * @ClassName: com.xh.common.log
 * @date: 2024/12/27 13:40
 * @Description:
 */
@Aspect
@Slf4j
@Component
@Order(1)
public class TaskTraceAop {

//    @Around("@annotation(anno)")
//    public Object distributedLock(ProceedingJoinPoint pjp, TaskTrace anno) throws Throwable{
//        try {
//            MDC.put("ASYNC_TASK_TRACE_ID","[ASYNC_TASK_TRACE_ID:" + UUID.randomUUID().toString().replace("-","") + "]");
//            return pjp.proceed();
//        } finally {
//            MDC.clear();
//        }
//    }

    // 处理所有带有 @TaskTrace 注解的方法
    @Around("@annotation(taskTrace)")
    public Object distributedLockWithAnnotation(ProceedingJoinPoint pjp, TaskTrace taskTrace) throws Throwable {
        return handleMethodExecution(pjp);
    }

    // 处理所有控制器中的方法
//    @Around("execution(* com..*.controller.*.*(..))")
//    @Around("execution(* com..*.web.*.*(..)) || execution(* com..*.system.*.*(..))")
//    ("execution(* com.ruoyi..*.web..*.*(..))")
    @Around("execution(* com..*.controller..*.*(..)) || execution(* com..*.system.*.*(..))")
    public Object distributedLockWithoutAnnotation(ProceedingJoinPoint pjp) throws Throwable {
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        if (!method.isAnnotationPresent(TaskTrace.class)) {
            return handleMethodExecution(pjp);
        }
        return pjp.proceed();
    }
    private Object handleMethodExecution(ProceedingJoinPoint pjp) throws Throwable {
        try {
            // 生成并记录追踪ID
            MDC.put("TRACE_ID", "[TRACE_ID:" + UUID.randomUUID().toString().replace("-", "") + "]");
            return pjp.proceed();
        } finally {
            MDC.clear();
        }
    }

}
